#include <my_header.h>

/* Usage: ./6_client_epoll */
int main(void){                          

    int socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    ERROR_CHECK(socket_fd, -1, "socket");

    // 服务端的ip地址和端口
    char *ip = "192.168.229.128";
    char *port = "8080";

    // 定义struct sockaddt类型结构体
    struct sockaddr_in client_addr;
    client_addr.sin_family = AF_INET;
    client_addr.sin_port = htons(atoi(port));
    client_addr.sin_addr.s_addr = inet_addr(ip);

    // 建立连接
    int res_connect = connect(socket_fd, (struct sockaddr *)&client_addr, sizeof(client_addr));
    ERROR_CHECK(res_connect, -1, "connect");

    // 创建epoll对象 epoll对象在内核
    // 包含监听集合(红黑树), 就绪集合(线性表)
    int epoll_fd = epoll_create(1);
    ERROR_CHECK(epoll_fd, -1, "epoll_create");

    // 添加监听事件：标准输入
    struct epoll_event event;
    event.events = EPOLLIN; // 读取操作
    event.data.fd = STDIN_FILENO; // 上述事件的对应的文件描述符
    int res_epolctl = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, STDIN_FILENO, &event);
    ERROR_CHECK(res_epolctl, -1, "epoll_ctl");

    // 添加监听事件：socket的接受数据(读就绪)
    event.data.fd = socket_fd;
    int res_epolctl2 = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, socket_fd, &event);
    ERROR_CHECK(res_epolctl2, -1, "epollc_ctl");

    int flag = 0;
    while(1)
    {
        // 构建就绪接受数组
        struct epoll_event events[10];
        memset(events, 0, sizeof(events));
        // 开始监听
        // epoll_wait：阻塞函数，没有监听的文件描述符就绪，将会阻塞在这里
        int num = epoll_wait(epoll_fd, events, 10, -1);
        // 遍历就绪集合
        for(int i=0; i<num; i++)
        {
            // 就绪fd
            int cfd = events[i].data.fd;
            if(cfd == STDIN_FILENO)
            {
                // 标准输入就绪
                char buf[60] = { 0 };
                // 读取标椎输入
                read(STDIN_FILENO, buf, sizeof(buf)-1);
                // 发送对端
                int res_send = send(socket_fd, buf, strlen(buf), 0);
                ERROR_CHECK(res_send, -1, "send");
            }else if(cfd == socket_fd)
            {
                // 对端数据到达，socket就绪
                char buf[60] = { 0 };
                // 读数据
                int res_recv = recv(socket_fd, buf, sizeof(buf), 0);
                if(res_recv == 0)
                {
                   printf("server closed! \n");
                   flag = 1;
                   break;
                 //   goto end;
                }
                printf("server  message : %s\n", buf);
                // write(STDOUT_FILENO, buf, sizeof(buf));
            }
        }
        if(flag != 0)
        {
            break;
        }
    }

// end:
    close(socket_fd);
    return 0;
}


